import path from 'path';
import fs, { Stats } from 'fs';

const defaultExclude = /(\.git|\.DS_Store|\/build)/;

const walk = function (dir: string, excludes: RegExp, done: (e: any, results?: any[]) => undefined) {
    let results: any = [];
    fs.readdir(dir, function (err: any, list: string[]) {
        if (err) return done(err);
        var i = 0;
        (function next() {
            var file = list[i++];
            if (!file) return done(null, results);
            file = path.resolve(dir, file);

            if (excludes.test(dir)) {
                next();
                return;
            }

            fs.stat(file, function (err: any, stat: Stats) {
                if (stat && stat.isDirectory()) {
                    walk(file, excludes, function (err, res) {
                        results = results.concat(res);
                        next();
                    });
                } else {
                    if (!excludes.test(file)) {
                        results.push(file);
                    }
                    next();
                }
            });
        })();
    });
};

const findFiles = async (dir: string, excludes: RegExp) => {
    return new Promise(resolve => {
        walk(dir, excludes, (err, list) => {
            resolve(list);
        });
    });
};

const queryFiles = async (rule: string[], excludes = defaultExclude) => {
    let files: any = [];
    if (Array.isArray(rule)) {
        for (let i = 0, len = rule.length; i < len; i++) {
            const item: any = rule[i];
            if (item.includes('**')) {
                const filterFiles = await findFiles(item.replace('**', ''), excludes);
                files = files.concat(filterFiles);
            } else {
                files.push(item);
            }
        }
    }
    return files;
};

export default queryFiles;
